// 路径动画模块
import { transform, getTransform } from 'ol/proj' // 坐标转换
import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import LineString from 'ol/geom/LineString'

import {
  Circle as CircleStyle,
  Fill,
  Icon,
  Stroke,
  Style,
  Text
} from 'ol/style'

/**
 * @description 创建动画路径--如果存在指定ID的路径不创建
 * @param {string} id 路径的ID
 * @param {array} aPointList 组成路径的的点
 * @param {boolean} isDisplayLen 是否显示路径长度
 * @param {Object} mapLayer 指定图层，用于绘制路径
 * @param {string} sMapSRS 地图引擎使用的空间参考坐标系
 * @param {number} fLenTxtPos 路径长度显示位置，默认0.5 标识路径中心， 0 标识首位置， 1 标识路径末尾
 * @return {object} {创建的路径geom和长度}
 */
function createPath (id, aPointList, isDisplayLen, mapLayer, sMapSRS, fLenTxtPos = 0.5) {
  // console.log('pathAnim ', id, aPointList, !mapLayer)
  if (!mapLayer) return
  const mapLayerSource = mapLayer.getSource()
  // console.log(mapLayerSource)
  if (!mapLayerSource || mapLayerSource.getFeatureById(id)) return // 指定的id路线存在
  // console.log(aPointList)
  const lineGeom = new LineString(aPointList) // 创建点列表--转换问题
  if (sMapSRS.toUpperCase() !== 'EPSG:4326') {
    // console.log(sMapSRS)
    lineGeom.applyTransform(getTransform('EPSG:4326', sMapSRS))
  }
  const lineFeature = new Feature({
    geometry: lineGeom,
    type: 'PATH'
  })
  lineFeature.setId(id)
  // 样式创建
  const defStyle = new Style({
    stroke: new Stroke({
      color: 'rgba(255, 0, 0, 1)',
      width: 1.8,
      lineDash: [5, 5]
    })
    // ,
    // text: new Text({ // 文本样式
    //   font: 'normal 14px 微软雅黑', // '12px Calibri,sans-serif',
    //   fill: new Fill({
    //     color: '#000'
    //   }),
    //   stroke: new Stroke({
    //     color: '#fff',
    //     width: 3
    //   })
    // })
  })
  lineFeature.setStyle(defStyle)
  mapLayerSource.addFeature(lineFeature)
  // 文字--路径长度(是否在路径上展示长度)
  const pathLen = Math.round(lineGeom.getLength()) / 1000 // '公里'
  if (isDisplayLen) {
    // const pathLen = Math.round(lineGeom.getLength()) / 1000 + '公里'
    // const pointCoord = lineGeom.getCoordinateAt(0.5) // 这里的坐标系已经改变了，可以直接使用！
    if (isNaN(fLenTxtPos)) {
      fLenTxtPos = 0.5
    }
    const pointCoord = lineGeom.getCoordinateAt(fLenTxtPos) // 默认0.5
    console.log(pathLen, pointCoord)
    const pointGeom = new Point(pointCoord)
    const txtFeature = new Feature({
      geometry: pointGeom
    })
    // const txtStyle = new Text({ // 文本样式
    //   font: 'normal 14px 微软雅黑', // '12px Calibri,sans-serif',
    //   fill: new Fill({
    //     color: '#000'
    //   }),
    //   stroke: new Stroke({
    //     color: '#fff',
    //     width: 3
    //   }),
    //   text: pathLen
    // })
    // defStyle.setText(txtStyle)
    const txtStyle = new Style({
      fill: new Fill({ // 矢量图层填充颜色，以及透明度
        color: 'rgba(255, 255, 255, 0.6)'
      }),
      stroke: new Stroke({ // 边界样式
        color: '#319FD3',
        width: 1
      }),
      text: new Text({ // 文本样式
        font: 'normal 14px 微软雅黑',
        fill: new Fill({
          color: '#000'
        }),
        stroke: new Stroke({
          color: '#fff',
          width: 3
        }),
        text: '' + pathLen
      })
    })
    txtFeature.setStyle(txtStyle)
    mapLayerSource.addFeature(txtFeature)
  }
  // 返回创建的路径和路径长度
  return { route: lineGeom, pathLen: pathLen }
}

/**
* @description 删除指定ID的路径
* @param {string} id 路径的ID
* @param {Object} mapLayer 指定图层，用于绘制路径
* @return {boole} 删除是否成功或失败（没有找到要删的Path）
 */
function delPathByID (id, mapLayer) {
  if (!mapLayer) return
  const mapLayerSource = mapLayer.getSource()
  if (!mapLayerSource) return // 指定的id路线存在
  const delTarget = mapLayerSource.getFeatureById(id)
  if (delTarget) {
    mapLayerSource.removeFeature(delTarget)
    return true // 找到并删除了指定path
  } else {
    return false // 没有删除操作
  }
}

/**
* @description 删除指定ID的路径
* @param {Object} mapLayer 指定图层，用于绘制路径
* @return {boole} 删除是否成功或失败（没有找到要删的Path）
 */
function delAllPath (mapLayer) {
  if (!mapLayer) return
  const mapLayerSource = mapLayer.getSource()
  if (!mapLayerSource) return // 指定的id路线存在
  const allFeatures = mapLayerSource.getFeatures()
  const arrLen = allFeatures.length
  for (let i = arrLen - 1; i >= 0; i--) {
    const iFeature = allFeatures[i]
    const sType = iFeature.get('type')
    if (sType === 'PATH') {
      mapLayerSource.removeFeature(iFeature)
    }
  }
}

/**
* @description 获取指定ID的路径
* @param {string} id 路径的ID
* @param {Object} mapLayer 指定图层，用于绘制路径 ? 是否要校验下PATH
* @return null
 */
function getPathByID (id, mapLayer) {
  if (!mapLayer) return
  const mapLayerSource = mapLayer.getSource()
  if (!mapLayerSource) return // 指定的id路线存在
  const iFeature = mapLayerSource.getFeatureById(id)
  if (iFeature) {
    // 返回指定的路径Feature
    // const geom = iFeature.getGeometry().getType()
    return iFeature.getGeometry()
  }
}

/**
* @description 检查当前图层是否有指定ID的路径
* @param {string} id 路径的ID
* @param {Object} mapLayer 指定图层，用于绘制路径
* @return null
 */
function hasPathByID (id, mapLayer) {
  if (!mapLayer) return
  const mapLayerSource = mapLayer.getSource()
  if (!mapLayerSource) return // 指定的id路线存在
  const iFeature = mapLayerSource.getFeatureById(id)
  if (iFeature) {
    // 路径存在，返回True
    return true
  } else {
    // 路径不存在，返回False
    return false
  }
}

// 路径动画精灵类
class PathSprite {
  // constructor (ID, distance = 1, speed = null, coord = [0, 0], life = 100, rotate = 0, scale = 1, icon = 'plane', style = null, subAct = null) {
  constructor (ID, icon, distance, speed) {
    this.id = ID
    this.life = 100
    this.speed = speed
    // this.speed = this.setSpeed(speed)
    this.rotate = 0
    this.scale = 1
    this.coord = null // (从路径中获取位置)
    this.lastTime = null // 动画上一帧时间
    this.speedFactor = 1
    this.distance = distance // 距离长度（总长度）
    this.currentLen = 0.0 // 当前走过的长度
    this.icon = icon // 动画精灵使用的icon
    this.style = null // 样式--可以从全局中调用！样式名称--可以画线用--长度--待定
    this.route = null // 精灵移动路径（创建的起点和目标连接线line）
    this.animating = false // 点检动画精灵是否动画中
    this.subAct = null // 后续操作
    // this.calcDuration() // 计算动画时长（秒）this.duration
    // this.createSprite()
  }

  // 设置速度因子
  // setSpeedFactor (fAnimaTime) {
  //   if (fAnimaTime && Number.isFinite(fAnimaTime)) {
  //     this.timeFactor = fAnimaTime
  //     this.calcDuration()
  //   }
  // }

  // 修改速度因子根据时间
  modifyDuration (iMinute) {
    if (Number.isFinite(this.distance) && Number.isFinite(this.speed) && this.speed) {
      const duration = this.distance / this.speed
      const f = Math.floor(duration / iMinute)
      this.speedFactor = f
    }
  }

  // 设置距离;最后保存为米
  setdistance (fLen, unit = 'km') {
    const sUnit = unit.toLowerCase()
    switch (sUnit) {
      case 'km':
        this.distance = fLen * 1000
        break
      case 'm':
        this.distance = fLen
        break
      default:
        this.distance = fLen
    }
  }

  // 设置速度;最后转换成每秒多少米
  setSpeed (fVelocity, unit = 'km/h') {
    const sUnit = unit.toLowerCase()
    switch (sUnit) {
      case 'km/h':
        // this.speed = fVelocity / 60 / 60 * 1000
        this.speed = fVelocity / 3600000
        break
      case 'mach':
        // 1 马赫=1225.08 千米/时;
        // this.speed = fVelocity * 1225.08 / 60 * 1000
        this.speed = fVelocity * 340.3
        break
      case 'm/s':
        // 米/秒
        this.speed = fVelocity
        break
      case 'm/m':
        // 米/分
        this.speed = fVelocity / 60
        break
      default:
        this.speed = fVelocity
    }
  }

  // 获取速度，返回的是米/秒
  getSpeed () {
    return this.speed
  }

  // 获取精灵ID
  getID () {
    return this.id
  }

  // 创建精灵：参数是路径line几何体
  createSprite (lineRoute, mapLayer) {
    if (!lineRoute) return
    this.route = lineRoute
    if (!mapLayer) return
    const mapLayerSource = mapLayer.getSource()
    if (!mapLayerSource) return
    this.coord = lineRoute.getFirstCoordinate()
    // 生成sprite的Feature
    // console.log(this.coord)
    const iFeature = new Feature({ // ol.Feature
      geometry: new Point(this.coord), // ol.geom.Point
      type: 'PATH_SPT' // path_sprite
    })

    iFeature.setId('PATH_SPT' + this.id)
    // 样式创建
    const defStyle = new Style({
      stroke: new Stroke({
        color: 'rgba(255, 0, 0, 1)',
        width: 1.8
        // lineDash: [5, 5]
      }),
      image: new Icon({
        crossOrigin: 'anonymous',
        anchor: [0.5, 0.5],
        // src: '/mapres/images/icon/' + this.sIconType + '/' + oStyleData.icon.src + '.png'
        src: '/mapres/images/icon/' + this.icon + '.png'
      })
    })
    iFeature.setStyle(defStyle)
    mapLayerSource.addFeature(iFeature)
  }

  setRoute (oRoute) {
    this.route = oRoute
  }

  // 获取精灵对应的feature
  getSpriteFeature (mapLayer) {
    if (!mapLayer) return
    const mapLayerSource = mapLayer.getSource()
    if (!mapLayerSource) return
    return mapLayerSource.getFeatureById('PATH_SPT' + this.id)
  }

  // 删除动画精灵
  delSprite (mapLayer) {
    if (!mapLayer) return
    const mapLayerSource = mapLayer.getSource()
    if (!mapLayerSource) return
    const iFeature = mapLayerSource.getFeatureById('PATH_SPT' + this.id)
    mapLayerSource.removeFeature(iFeature)
  }

  // 更新位置oRoute--当前使用的路径
  moveFeature (mapLayer) {
    const time = parseInt(Date.now() / 1000)
    const elapsedTime = time - this.lastTime // 获取经过时间-秒
    if (elapsedTime < 1) return
    // console.log(this.currentLen, this.speed, this.speedFactor, elapsedTime)
    this.currentLen = (this.currentLen + (this.speed * this.speedFactor * elapsedTime))
    this.lastTime = time
    let fraction = this.currentLen / this.distance
    // console.log(fraction, this.currentLen, this.distance)
    if (fraction > 1) {
      fraction = 1
      this.animating = false
      this.delSprite(mapLayer)
      return
    }
    const currentCoordinate = this.route.getCoordinateAt(fraction)
    // console.log(currentCoordinate)
    const dx = currentCoordinate[0] - this.coord[0]
    const dy = currentCoordinate[1] - this.coord[1]
    const iFeature = this.getSpriteFeature(mapLayer)
    const rotation = Math.atan2(dy, dx)
    // console.log(rotation)
    if (this.rotate !== rotation) {
      this.rotate = rotation
      iFeature.getStyle().getImage().setRotation(-this.rotate + 1.57) // PI/2
    }
    // const iFeature = this.getSpriteFeature(mapLayer)
    const geometry = iFeature.getGeometry()
    geometry.translate(dx, dy)
    // console.log(iFeature)
    this.coord = currentCoordinate
    // console.log(this.distance - this.currentLen)
    // console.log((this.distance - this.currentLen) / (this.speed * this.speedFactor))
    const targetDistance = this.distance - this.currentLen
    const iTime = targetDistance / (this.speed * this.speedFactor)
    return { id: this.id, coord: currentCoordinate, distance: targetDistance, time: iTime }
    // return data
    // console.log(data)
    // this.$emit('pathAnim', data)
  }
  // moveFeature (event) {
  //   console.log(this.currentLen)
  //   const time = event.frameState.time
  //   const elapsedTime = time - this.lastTime
  //   console.log(this.currentLen, this.speed, this.speedFactor, elapsedTime)
  //   this.currentLen = (this.currentLen + (this.speed * this.speedFactor * elapsedTime)) // 1e6) % 2
  //   this.lastTime = time
  //   console.log(time, elapsedTime, this.currentLen)
  // }

  // 开始动画
  startAnimation () {
    this.animating = true
    this.lastTime = parseInt(Date.now() / 1000)
  }
  // startAnimation (mapLayer) {
  //   this.animating = true
  //   this.lastTime = Date.now()
  //   // console.log(mapLayer)
  //   mapLayer.on('postrender', this.moveFeature)
  //   console.log(mapLayer)
  // }

  // 将最后时间设置为当前时间--相当于暂停
  setLastTime () {
    this.lastTime = parseInt(Date.now() / 1000)
  }
}

export { createPath, delPathByID, delAllPath, getPathByID, hasPathByID, PathSprite }
